using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityGameFramework.Runtime;
using Object = UnityEngine.Object;

namespace StarForce.Hotfix
{
    public class Collection<T> where T : ItemContext, new()
    {
        private readonly List<T> m_ItemList = new List<T>();

        private Transform m_Parent;

        private GameObject m_Temp;

        private LinkedList<GameObject> m_Stack;

        public int Count
        {
            get { return m_ItemList.Count; }
        }

        public List<T> ItemList
        {
            get { return m_ItemList; }
        }

        /// <summary>
        /// 列表collection 构造函数
        /// </summary>
        /// <param name="parent">item的父元素</param>
        /// <param name="tempParent">itemtemp的父元素</param>
        public Collection(Transform parent, GameObject tempParent)
        {
            m_Parent = parent;
            m_Stack = new LinkedList<GameObject>();
            ComponentChildBind componentChildBind;
            if (tempParent.TryGetComponent(out componentChildBind))
            {
                m_Temp = componentChildBind.Child;
                // m_ComponentChildBind.StartCoroutine("StartAdd");
                if (m_Temp == null)
                {
                    Log.Error("template is null");
                }
            }
            else
            {
                Log.Error("ComponentChildBind is valid");
            }
        }

//        public T Add()
//        {
//            if (m_Temp == null)
//            {
//                Log.Error("Template is invalid");
//                return null;
//            }
//
//            T item = new T();
//            GameObject itemObject;
//            if (m_Stack.Count > 0)
//            {
//                itemObject = m_Stack.First();
//                m_Stack.RemoveFirst();
//                itemObject.SetActive(true);
//            }
//            else
//            {
//                itemObject = Object.Instantiate<GameObject>(m_Temp, m_Parent);
//            }
//
//            Transform itemTransform = itemObject.transform;
//            itemTransform.localScale = Vector3.one;
//            itemTransform.transform.SetSiblingIndex(m_ItemList.Count);
//            item.Index = m_ItemList.Count;
//            item.GameObject = itemObject;
//            item.GetBindComponents();
//
//            m_ItemList.Insert(item.Index, item);
//            return item;
//        }

        /// <summary>
        /// 插入一个Item
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T OnItemInsert(int index)
        {
            if (m_Temp == null)
            {
                Log.Error("Template is invalid");
                return null;
            }

            GameObject itemObject;
            if (m_Stack.Count > 0)
            {
                itemObject = m_Stack.First();
                m_Stack.RemoveFirst();
                itemObject.SetActive(true);
            }
            else
            {
                itemObject = Object.Instantiate<GameObject>(m_Temp, m_Parent);
            }

            Transform itemTransform = itemObject.transform;
            itemTransform.localScale = Vector3.one;
            itemTransform.transform.SetSiblingIndex(index);
            T item = new T();
            item.Index = index;
            item.GameObject = itemObject;
            item.GetBindComponents();
            m_ItemList.Insert(index, item);
            // UpdateContext();
            return item;
        }

        /// <summary>
        /// 获取一个Item
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T GetItem(int index)
        {
            if (index > m_ItemList.Count || index < 0 || m_ItemList.Count == 0)
            {
                Log.Error("index is outof range");
            }

            return m_ItemList[index];
        }

        /// <summary>
        /// 获取一个Item  没有就增加一个
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T GetOrAddItem(int index)
        {
            if (index < 0 || index >= m_ItemList.Count)
            {
                return OnItemInsert(index);
            }

            return GetItem(index);
        }

        /// <summary>
        /// 移除一个元素
        /// </summary>
        /// <param name="index"></param>
        public void RemoveItem(int index)
        {
            GameObject gameObject = m_ItemList[index].GameObject;
            m_ItemList.RemoveAt(index);
            UnityEngine.Object.Destroy(gameObject);
//            UpdateContext();
        }

        /// <summary>
        /// 回收一个元素
        /// </summary>
        /// <param name="index"></param>
        public void RecoveryItem(int index)
        {
            GameObject gameObject = m_ItemList[index].GameObject;
            m_Stack.AddLast(m_ItemList[index].GameObject);
            m_ItemList.RemoveAt(index);
            gameObject.SetActive(false);

//            UpdateContext();
        }

        /// <summary>
        /// 清除列表
        /// </summary>
        public void Clear()
        {
            for (int i = 0; i < m_ItemList.Count; i++)
            {
                m_ItemList[i].Clear();
                m_ItemList[i].GameObject.SetActive(false);
                m_Stack.AddLast(m_ItemList[i].GameObject);
            }

            m_ItemList.Clear();
        }

        public void DestroyAll()
        {
            for (int i = 0; i < m_ItemList.Count; i++)
            {
                Object.Destroy(m_ItemList[i].GameObject);
            }

            m_ItemList.Clear();
        }

        /// <summary>
        /// 更新索引(防止改变多个元素时多次更新，需要手动调用)
        /// </summary>
        public void UpdateContext()
        {
            for (int i = 0; i < m_ItemList.Count; i++)
            {
                m_ItemList[i].Index = i;
            }
        }
    }
}